home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / xcoral / xcoral.lha / xcoral-1.72 / file_select.c < prev    next >
C/C++ Source or Header  |  1993-02-19  |  21KB  |  797 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <X11/Xlib.h>
  16. #include <stdio.h>
  17. #ifdef apollo
  18. #include <sys/dir.h>
  19. #define dirent direct
  20. #else
  21. #include <dirent.h>
  22. #endif
  23. #include <sys/param.h>
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #ifdef apollo
  27. #define S_ISDIR
  28. #else
  29. #include <malloc.h>
  30. #endif
  31. #include <string.h>
  32.  
  33. #include "text.h"
  34. #include "options.h"
  35. #include "flist.h"
  36.  
  37. extern Display *dpy;
  38. extern char  *getcwd();
  39.  
  40. #define FS_SHADOW     6
  41. #define FS_SPACE    5
  42. #define FS_BUFFER_SIZE    10000
  43.  
  44. typedef struct {
  45.     Window         frame, shadow, title, dir, main, ok, cancel;
  46. /* new */    Window        dirframe, fileframe, dirtitle, filetitle, dirtext, filetext;
  47. /* new */    Window        fieldframe, fieldtext;
  48.     unsigned long     fg, bg, ts, bs, text_fg, text_bg;
  49.     XFontStruct    *font;
  50.         GC        gc;
  51.         int         width, height, title_height, button_width, button_height;
  52.         Text        *text;
  53.         Buf        *buf;
  54.         SWin        *scroll;
  55.         int        select;
  56.         int        m_width, m_height;
  57.         char        *dirname;
  58.     Time        click_time;
  59.     Time        old_click;
  60. } Selector;
  61.  
  62. /*
  63.  * Public
  64.  */
  65. extern void InitFileSelector ();
  66. extern char *GetStringFromSelect ( /* parent, type */ );
  67.  
  68. /* 
  69.  * Private
  70.  */
  71. static Selector fs;
  72. static void ButtonFileSelect (), ExposeFileSelect (), SetParams (),
  73.     CleanButton (),    RefreshFileSelect (), RefreshDirWindow (),
  74.     SelectFileItem (), UpdateFileItem (),ConfigFileSelect (),
  75.     SortFiles (), UnmapFileSelect ();
  76. static int MyCompare ();
  77.  
  78.  
  79. /*
  80. **    Function name : InitFileSelector
  81. **
  82. **    Description : Creation des fenetres, boutons, scroll etc...
  83. **    Input : 
  84. **    Ouput :
  85. */
  86. void InitFileSelector ()
  87. {
  88.     XSetWindowAttributes att_f;    
  89.     Window     root;
  90.     int     screen;
  91.     unsigned long black, white;
  92.     XGCValues     gcv;
  93.  
  94.         screen = DefaultScreen ( dpy );
  95.     root = RootWindow ( dpy, screen );
  96.     black = BlackPixel ( dpy, DefaultScreen ( dpy ));
  97.     white = WhitePixel ( dpy, DefaultScreen ( dpy ));
  98.  
  99.     fs.fg = (DefaultDepth ( dpy, screen ) == 1) ? black : GetOpColor ( OP_MENU_FG );
  100.     fs.bg = (DefaultDepth ( dpy, screen ) == 1) ? white : GetOpColor ( OP_MENU_BG );
  101.     fs.text_bg = GetOpColor ( OP_TEXT_BG );
  102.     fs.text_fg = GetOpColor ( OP_TEXT_FG );
  103.     fs.ts = GetOpColor ( OP_MENU_TS );
  104.     fs.bs = GetOpColor ( OP_MENU_BS );
  105.     fs.font = GetOpFont ( OP_TEXT_FONT );
  106.  
  107.     fs.gc = XCreateGC ( dpy, DefaultRootWindow ( dpy ), 0,  &gcv );
  108.      XCopyGC ( dpy, DefaultGC (dpy, screen ), (~0), fs.gc );
  109.  
  110.     XSetFont ( dpy, fs.gc, fs.font -> fid );
  111.     XSetForeground ( dpy, fs.gc, fs.fg );
  112.     XSetBackground ( dpy, fs.gc, fs.bg );
  113.  
  114.     fs.title_height = fs.font -> ascent + fs.font-> descent + 8;
  115.     fs.button_height = fs.font -> ascent + fs.font-> descent + 8;
  116.     fs.width = DisplayWidth ( dpy,DefaultScreen ( dpy )) / 2;
  117.     fs.height = DisplayHeight ( dpy,DefaultScreen ( dpy ))/2;
  118.  
  119.         att_f.win_gravity = NorthWestGravity;
  120.     att_f.event_mask = 0;
  121.     att_f.override_redirect = False;
  122.     att_f.do_not_propagate_mask = NoEventMask;
  123.     att_f.cursor = None;
  124.     att_f.win_gravity = NorthWestGravity;
  125.  
  126.         fs.frame = XCreateWindow ( dpy, root, 0, 0, fs.width, fs.height, 0, 0,
  127.         InputOutput, CopyFromParent,
  128.         CWWinGravity | CWEventMask | CWOverrideRedirect |
  129.         CWDontPropagate | CWCursor, &att_f );
  130.  
  131.                 fs.shadow = XCreateSimpleWindow ( dpy, fs.frame, FS_SHADOW, FS_SHADOW, 
  132.         fs.width, fs.height, 0, black, black);
  133.  
  134.         fs.title = XCreateSimpleWindow (dpy, fs.frame, 
  135.         0, 0, fs.width, fs.title_height, 0 , black, fs.bg );
  136.  
  137.             fs.dir = XCreateSimpleWindow (dpy, fs.frame, 
  138.         0, fs.title_height, fs.width, fs.title_height, 0 , black, fs.bg );
  139.  
  140.         fs.main = XCreateSimpleWindow (dpy, fs.frame, 
  141.         0, (2*(fs.title_height)),
  142.                 fs.width, fs.height - fs.title_height, 0, black, fs.bg );
  143.            fs.button_width = XTextWidth ( fs.font, "  Ok...  ", 9 ) + 10;        
  144.     fs.ok = XCreateSimpleWindow (dpy, fs.main, 0, 0,
  145.         fs.button_width,fs.button_height, 0, black, fs.bg );
  146.     fs.cancel = XCreateSimpleWindow (dpy, fs.main, 0, 0,
  147.         fs.button_width, fs.button_height, 0, black, fs.bg );
  148.  
  149.     XSelectInput ( dpy, fs.title, ExposureMask );
  150.         XSelectInput ( dpy, fs.dir, ExposureMask );
  151.     XSelectInput ( dpy, fs.main, ExposureMask );
  152.     XSelectInput ( dpy, fs.ok, ExposureMask | ButtonPressMask | ButtonReleaseMask);
  153.     XSelectInput ( dpy, fs.cancel, ExposureMask | ButtonPressMask | ButtonReleaseMask);    
  154.  
  155.         fs.text = ( Text * ) MakeTextWindow ( dpy, fs.main, FS_SPACE, FS_SPACE );
  156.     fs.scroll = ( SWin  * ) MakeScroll ( dpy, fs.main,  0, FS_SPACE ); 
  157.     fs.text -> swin = fs.scroll;
  158.     fs.scroll -> text = (char *) fs.text;
  159.     fs.text -> mwin = 0;
  160.     fs.buf = (Buf *) GetBuffer ( (unsigned) FS_BUFFER_SIZE );
  161.     fs.text -> buf = fs.buf;
  162.     fs.select = 0;
  163.     fs.dirname = 0;
  164.     fs.old_click = 0;
  165. }
  166.  
  167.  
  168. /*
  169. **    Function name : ReadDir
  170. **
  171. **    Description :  Charge les noms de fichiers dans le buffer.
  172. **    Input : Le nom de la directorie.
  173. **    Ouput : 0 si OK -1 sinon
  174. */
  175. static int ReadDir ( dir )
  176. char *dir;
  177. {
  178.     DIR *dirp;
  179.     struct dirent *dp;
  180.          register int n;
  181.         char **tmp;
  182.         register int i=0;
  183.         register int dir_len = 0;
  184.  
  185.     dirp = opendir( dir );
  186.         if ( dirp == 0 ) 
  187.         return -1;
  188.  
  189.     ClearBuffer ( fs.buf ); 
  190.     for (dp = readdir(dirp); dp != 0; dp = readdir(dirp)) 
  191.             dir_len ++;
  192.         (void) closedir ( dirp );
  193.         dirp = opendir( dir );
  194.         tmp = (char **) malloc ( (unsigned) ( sizeof (char *) * (dir_len + 2)));
  195.  
  196.     for (dp = readdir(dirp); dp != 0; dp = readdir(dirp)) {
  197.         if ( (dp->d_name != 0) && (strlen(dp->d_name) != 0) ) {
  198.                         tmp [i] = (char *) malloc ( (unsigned) strlen (dp->d_name) + 2);
  199.             (void) strcpy ( (char *) tmp[i], dp->d_name );
  200.             i++;
  201.             }
  202.         }
  203.     qsort ( (char *) tmp, i, sizeof ( char *), MyCompare ); 
  204.     for ( n = 0; n < i; n++ ) {
  205.                 InsertNchar ( fs.buf, (char *) tmp [n], 
  206.                         strlen ((char *) tmp [n] ));
  207.               if ( tmp[n] != 0 )
  208.             (void) free ( (char *) tmp[n] );
  209.         InsertNchar ( fs.buf, "\n", 1 );
  210.         }
  211.        if ( tmp != 0 )
  212.         (void) free ( (char *) tmp );
  213.     SetParams ( FILESELECT, dir );
  214.         (void) closedir ( dirp );
  215.         return 0;
  216. }
  217.  
  218.  
  219. /*
  220. **    Function name : SetParams
  221. **
  222. **    Description : Positionne quelques parametres, en fonction
  223. **        du type d'objet a afficher.
  224. **    Input : Le type, la directorie.
  225. **    Ouput :
  226. */
  227. static void SetParams ( type, dir )
  228.     register int type;
  229.     register char *dir;
  230. {
  231.     register char *pathname;
  232.        register int n;
  233.  
  234.     fs.text -> modif = True;
  235.     (void) strcpy ( (char *) fs.text -> filename, "NoName" );
  236.     n = GetNumberOfLineInBuf ( fs.text -> buf );
  237.     fs.text -> lines_in_buf = n;
  238.     SetScrollLine ( fs.text -> swin, n );
  239.     HoleToLeft ( fs.buf );
  240.     
  241.     if ( fs.dirname != 0 )
  242.         (void) free ( fs.dirname );
  243.  
  244.     switch ( type ) {
  245.         case FILESELECT:
  246.                 pathname = (char *) malloc ( (unsigned) MAXPATHLEN + 2 );
  247.             (void) getcwd ( (char*) pathname, MAXPATHLEN + 2 );
  248.             if ( strcmp ( dir, "." ) == 0 ) {
  249.                     fs.dirname = ( char *) malloc ( (unsigned) strlen (pathname) +2 );
  250.                     (void) strcpy ( fs.dirname, (char *) pathname );
  251.             }
  252.             else {
  253.                     fs.dirname = ( char *) malloc ( (unsigned) strlen (dir) +2 );
  254.                     (void) strcpy ( fs.dirname, dir );
  255.             }
  256.                   if ( pathname != 0 )
  257.                     (void)  free ( pathname );
  258.             break;
  259.         case KILLBUF:
  260.             fs.dirname = ( char *) malloc ( (unsigned) 64 );
  261.                 (void) strcpy ( fs.dirname, "Select : " );
  262.             break;
  263.         case OPENFILES:
  264.             fs.dirname = ( char *) malloc ( (unsigned) 256 );
  265.                 (void) strcpy ( fs.dirname, "Select : " );
  266.             break;
  267.         default:
  268.             break;    
  269.     }
  270. }
  271.  
  272.  
  273. /*
  274. **    Function name : MyCompare
  275. **
  276. **    Description : Compare  2 chaines
  277. **    Input : 2 tableaux de chaines
  278. **    Ouput : Vrai si s1 = s2 Faux sinon
  279. */
  280. static int MyCompare ( s1, s2 )
  281.     register char **s1, **s2;
  282. {
  283.     return ( strcmp ( *s1, *s2 ));
  284. }
  285.  
  286.  
  287. /*
  288. **    Function name : GetStringFromSelect
  289. **
  290. **    Description : Retourne la chaine selectionnee.
  291. **    Input : La fenetre parent, le type d'objet
  292. **    Ouput : La chaine.
  293. */
  294. char *GetStringFromSelect ( window, type )
  295. Window window;
  296. register int type;
  297. {
  298.     register char *str, *tmp;
  299.     XEvent event;
  300.     int len;
  301.  
  302.     switch ( type ) {
  303.         case FILESELECT:
  304.                  (void) ReadDir ( "." );
  305.             break;
  306.         case KILLBUF:
  307.                   ClearBuffer ( fs.buf );         
  308.             (void) LoadKillBuffer ( fs.buf );
  309.             SetParams ( KILLBUF, (char *) 0 );
  310.             break;
  311.         case OPENFILES:
  312.             ClearBuffer ( fs.buf );
  313.             LoadFileNames ( fs.buf ); 
  314.             SetParams ( OPENFILES, (char *) 0 );
  315.             break;
  316.         default:
  317.         break;
  318.         
  319.     }
  320.     ConfigFileSelect ( window );
  321.  
  322.        XGrabPointer ( dpy, fs.frame, True, ButtonReleaseMask, GrabModeAsync,
  323.         GrabModeAsync, fs.frame, None, CurrentTime );
  324.  
  325.        for (;;) {
  326.         XNextEvent ( dpy, &event );
  327.         switch ( event.type ) {
  328.         case Expose:
  329.             ExposeFileSelect ( event.xexpose.window, type );
  330.             break;
  331.         case ButtonPress:
  332.             fs.click_time = event.xbutton.time;
  333.             if ( event.xbutton.window == fs.cancel 
  334.                 || event.xbutton.window == fs.ok 
  335.                 || FsDoubleClick () == True ) {
  336.                 CleanButton ( event.xbutton.window, event.xbutton.button );
  337.                 if ( event.xbutton.window != fs.cancel ) {
  338.                     tmp = (char *) GetCurrentLine ( fs.buf, &len );
  339.                     tmp [len] = 0;
  340.                     switch ( type ) {
  341.                     case FILESELECT:
  342.                         str = (char *) malloc ( (unsigned) len + strlen(fs.dirname) + 2 );
  343.                         if ( strcmp ( tmp, "." ) == 0 || fs.select == 0 ) 
  344.                             (void) sprintf ( str, "%s", fs.dirname );
  345.                            else {
  346.                             if ( strcmp ( fs.dirname, "/" ) == 0 ) 
  347.                                 (void) sprintf ( str, "/%s", tmp );    
  348.                             else
  349.                                       (void) sprintf ( str, "%s/%s", fs.dirname, tmp );
  350.                         }
  351.                         break;
  352.                     case KILLBUF:
  353.                     case OPENFILES:
  354.                         str = (char *) malloc ( (unsigned) len + 2 );
  355.                         (void) sprintf ( str, "%s", tmp );
  356.                         break;
  357.                     default:
  358.                         break;
  359.                     }
  360.                     fs.select = 0;
  361.                     XUngrabPointer ( dpy, CurrentTime );
  362.                     UnmapFileSelect ();
  363.                     return ( str );
  364.                 }
  365.                 fs.select = 0;
  366.                 XUngrabPointer ( dpy, CurrentTime );
  367.                 UnmapFileSelect ();
  368.                 return 0;                
  369.             }
  370.             else
  371.                 ButtonFileSelect ( event.xbutton.window,
  372.                     event.xbutton.x, event.xbutton.y, type );
  373.             break;
  374.         default :
  375.             break;    
  376.         }
  377.     }
  378. }
  379.  
  380.  
  381. /*
  382. **    Function name : FsDoubleClick
  383. **
  384. **    Description : 
  385. **    Input : 
  386. **    Ouput :
  387. */
  388. int FsDoubleClick ()
  389. {
  390.     if ( fs.old_click == 0 ) 
  391.         return False;
  392.     
  393.     if ( (fs.click_time - fs.old_click) < 200)
  394.         return True;
  395.     else
  396.         return False;
  397. }
  398.  
  399.  
  400. /*
  401. **    Function name : ButtonFileSelect
  402. **
  403. **    Description : Traitement de l'evennement 'ButtonPress'
  404. **    Input : La fenetre, la position, le type. 
  405. **    Ouput :
  406. */
  407. static void ButtonFileSelect ( w, x, y, type )
  408. Window w;
  409. register int x, y;
  410. register int type;
  411. {
  412.     int result;
  413.  
  414.     if ( ButtonPressInScroll ( fs.scroll,w, y, &result )) {
  415.         UpdateFileItem ( fs.select );
  416.         switch ( result ) {
  417.         case CURSOR:
  418.             /* Pour mettre a jour la ligne courante */
  419.             TextCursorOn ( fs.text );
  420.             TextCursorOff ( fs.text );
  421.             if ( (TextInBuf ( fs.text ) == True) 
  422.                 && ( fs.text -> lines_in_buf > 1 )) {
  423.                 HandleScrollBar ( dpy, fs.scroll, ScrollNLine );
  424.                 RefreshScrollBar ( dpy, fs.scroll );
  425.                 XGrabPointer ( dpy, fs.frame, True, ButtonReleaseMask, GrabModeAsync,
  426.                     GrabModeAsync, fs.frame, None, CurrentTime );
  427.             }
  428.             break;
  429.         case NEXT:
  430.             TextCursorOff ( fs.text );
  431.             NextPage ( fs.text  );
  432.             break;
  433.         case PREVIOUS:
  434.             TextCursorOff ( fs.text );
  435.             PreviousPage ( fs.text );
  436.             break;
  437.         }
  438.         TextCursorOn ( fs.text );
  439.         TextCursorOff ( fs.text );
  440.         UpdateFileItem ( fs.select );
  441.     }
  442.     else if ( w == fs.text -> window ) 
  443.         SelectFileItem ( x, y, type );
  444. }
  445.  
  446.  
  447. /*
  448. **    Function name : ExposeFileSelect
  449. **
  450. **    Description : Traitement de l'evennement 'Expose'
  451. **    Input : La fenetre, le type
  452. **    Ouput :
  453. */
  454. static void ExposeFileSelect ( w, type )
  455.     Window w;
  456.     register int type;
  457. {
  458.     register int x;
  459.     XEvent event;
  460.     char s_title [32];
  461.  
  462.     switch ( type ) {
  463.         case FILESELECT:
  464.             (void) strcpy ( s_title, "File Selection" );
  465.             break;
  466.         case KILLBUF:
  467.             (void) strcpy ( s_title, "Kill Buffers" );
  468.             break;
  469.         case OPENFILES:
  470.             (void) strcpy ( s_title, "Open Files" );
  471.             break;
  472.         default:
  473.             break;
  474.     }
  475.  
  476.     if ( w == fs.title ) {
  477.             x = XTextWidth ( fs.font, s_title, 14 );
  478.         XDrawString ( dpy, fs.title, fs.gc, (fs.m_width - x)/2,
  479.             fs.font -> ascent + 5, s_title, strlen (s_title) );
  480.         Display3D ( dpy, fs.title, fs.ts, fs.bs, 1, 0 );
  481.     }
  482.     if ( w == fs.dir ) {
  483.         FirstPage ( fs.text );
  484.         if ( type == FILESELECT ) 
  485.             RefreshDirWindow ( fs.dirname, FILESELECT  );
  486.         else
  487.             RefreshDirWindow ( fs.dirname, KILLBUF  );
  488.     }
  489.     else if ( w == fs.main ) 
  490.         Display3D ( dpy, fs.main, fs.ts, fs.bs, 1, 0 );
  491.     else if ( w == fs.ok ) {
  492.         switch ( type ) {
  493.             case FILESELECT:
  494.                 (void) strcpy ( s_title, "  Ok...  " );
  495.                 break;
  496.             case KILLBUF:
  497.                 (void) strcpy ( s_title, "Restore" );
  498.                 break;
  499.             case OPENFILES:
  500.                 (void) strcpy ( s_title, "Raise" );
  501.                 break;
  502.             default:
  503.                 break;
  504.         }
  505.         x = XTextWidth ( fs.font, s_title, strlen (s_title) );
  506.         XDrawString ( dpy, fs.ok, fs.gc,  (fs.button_width - x)/2,
  507.             fs.font -> ascent + 3, s_title, strlen (s_title) );
  508.         Display3D ( dpy, fs.ok, fs.ts, fs.bs, 1, 0 );
  509.     }
  510.     else if ( w == fs.cancel ) {
  511.         x = XTextWidth ( fs.font, "Cancel", 6 );
  512.         XDrawString ( dpy, fs.cancel, fs.gc, (fs.button_width - x)/2,
  513.             fs.font -> ascent + 3, "Cancel", 6 );
  514.         Display3D ( dpy, fs.cancel, fs.ts, fs.bs, 1, 0 );
  515.     }
  516.     else if ( w == fs.text -> window ) {
  517.         RefreshFileSelect ();
  518.     }
  519.     else if ( w == fs.scroll -> frame ) {
  520.         RefreshScrollFrame ( dpy,  fs.scroll );
  521.     }
  522.     else if ( w == fs.scroll -> scroll ) {
  523.         RefreshScrollBar ( dpy, fs.scroll );
  524.     }
  525.     while ( XCheckWindowEvent ( dpy, w, ExposureMask, &event ));
  526. }
  527.  
  528.  
  529. /*
  530. **    Function name : CleanButton
  531. **
  532. **    Description : Remet un boutton dans sa forme initiale.
  533. **    Input : La fenetre, le boutton.
  534. **    Ouput :
  535. */
  536. static void CleanButton ( w, button )
  537.     Window w;
  538.     unsigned int button;
  539. {
  540.     Display3D ( dpy, w, fs.ts, fs.bs, 1, 1 ); 
  541.     XGrabPointer ( dpy, w, True, ButtonReleaseMask, GrabModeAsync,
  542.         GrabModeAsync, w, None, CurrentTime );
  543.     WaitButtonRelease ( button );
  544.     Display3D ( dpy, w, fs.ts, fs.bs, 1, 0 );
  545. }
  546.  
  547.  
  548. /*
  549. **    Function name : RefreshFileSelect
  550. **
  551. **    Description : Postionne les elements
  552. **    Input : 
  553. **    Ouput :
  554. */
  555. static void RefreshFileSelect ()
  556. {
  557.     XClearWindow ( dpy, fs.text -> window );
  558.     Display3D ( dpy, fs.text -> window, fs.ts, fs.bs, 2, 1 ); 
  559.     ClipOn ( fs.text, 0 );
  560.     SetLinesTable ( fs.text );
  561.     RefreshPage ( fs.text );
  562.     ShowScrollFrame ( dpy, fs.text -> swin );    
  563.     ClipOff ( fs.text );
  564. }
  565.  
  566.  
  567. /*
  568. **    Function name : RefreshDirWindow
  569. **
  570. **    Description : Met a jour le texte dans le fenetre dir
  571. **    Input : Le nom, le type.
  572. **    Ouput :
  573. */
  574. static void RefreshDirWindow ( dir, type )
  575.     register char *dir;
  576.     register int type;
  577. {
  578.     register int start, width;
  579.     register char *old = dir;
  580.  
  581.     XClearWindow ( dpy, fs.dir );
  582.        if ( type == KILLBUF || type == OPENFILES ) {
  583.               XDrawString ( dpy, fs.dir, fs.gc, MARGE, fs.font -> ascent + 5, dir, strlen(dir));
  584.               Display3D ( dpy, fs.dir, fs.ts, fs.bs, 1, 0 );    
  585.               return;
  586.         }
  587.     start = MARGE + XTextWidth ( fs.font, "Dir : ", 6 ) + 3;
  588.     width = fs.m_width - start -MARGE - XTextWidth ( fs.font, "...", 3 );
  589.     while ( XTextWidth ( fs.font, dir, strlen(dir)) > width ) 
  590.         dir ++;
  591.     XDrawString ( dpy, fs.dir, fs.gc, MARGE, fs.font -> ascent + 5, "Dir : ", 6 );
  592.     if ( old != dir ) {
  593.         XDrawString ( dpy, fs.dir, fs.gc, start, fs.font -> ascent + 5, "...", 3 );
  594.          XDrawString ( dpy, fs.dir, fs.gc,
  595.             start + XTextWidth ( fs.font, "...", 3 ), 
  596.             fs.font -> ascent + 5, dir, strlen(dir) );        
  597.     }
  598.     else
  599.          XDrawString ( dpy, fs.dir, fs.gc,
  600.             start, fs.font -> ascent + 5, dir, strlen(dir) );
  601.     Display3D ( dpy, fs.dir, fs.ts, fs.bs, 1, 0 );
  602. }
  603.  
  604.  
  605. /*
  606. **    Function name : SlectFileItem
  607. **
  608. **    Description : Selection d'un item.
  609. **    Input : La position, le type.
  610. **    Ouput :
  611. */
  612. static void SelectFileItem ( x, y, type )
  613. register int x, y;
  614. register int type;
  615. {
  616.     register int n;
  617.         register char *s, *end_name;
  618.         int len;
  619.         struct stat st;
  620.     char *tmp, *name_select;
  621.  
  622.     (void) MoveToXYinTextWindow (  fs.text,  x, y );
  623.     TextCursorOn ( fs.text );
  624.     TextCursorOff ( fs.text );
  625.  
  626.     if ( (n = fs.text -> no_current_line) >= fs.text -> lines_in_buf )
  627.         return;
  628.  
  629.     UpdateFileItem ( fs.select ); /* Eteint l'item courant */
  630.     UpdateFileItem ( n );     /* Allume l'item selectionne */
  631.     fs.select = n;
  632.     s = (char * ) GetCurrentLine ( fs.buf, &len );
  633.    
  634.        if ( type == KILLBUF || type == OPENFILES ) {
  635.               (void) sprintf ( fs.dirname, "Select : " );
  636.               (void) strncat ( fs.dirname, s, len );
  637.         len += strlen ( "Select : " );
  638.         fs.dirname [len] = '\0';
  639.               RefreshDirWindow ( fs.dirname, KILLBUF );
  640.         fs.old_click = fs.click_time;
  641.               return;        
  642.      }
  643.     name_select = (char *) malloc ( (unsigned) len + 2 );
  644.     (void) strncpy ( name_select, s, len);
  645.     name_select [len] = '\0';
  646. #ifdef DEBUG
  647.     fprintf ( stderr, "\nfs.dirname = %s\nname_select = %s\n", fs.dirname, name_select );
  648. #endif
  649.             len = strlen(fs.dirname) + strlen(name_select);
  650.     tmp = (char *) malloc ( (unsigned) len + 2 ); 
  651.     (void) sprintf ( tmp, "%s/%s", fs.dirname, name_select );
  652.         
  653.         if ( (strcmp ( tmp, "/.." ) == 0) || (strcmp ( name_select, ".") == 0) ) {
  654.            if ( tmp != 0 )
  655.                     (void) free (tmp);
  656.            if ( name_select != 0 )
  657.                     (void) free (name_select);
  658.                 return;
  659.     }
  660.     if ( stat ( tmp, &st ) == 0 ) {
  661.         if ( S_ISDIR(st.st_mode) != 0 ) {
  662.             fs.old_click = 0;                    
  663.             if ( strcmp (name_select, "..") == 0 ) {
  664.                        end_name = (char * ) strrchr ( (char *) fs.dirname, '/' );
  665.                 len = strlen(fs.dirname) - strlen(end_name);
  666.                 tmp [len] = 0;
  667.                 if ( len == 0 ) {    /* Root */
  668.                     (void) strncpy ( tmp, "/", 1 );
  669.                     tmp [1] = 0;
  670.                 }
  671.             }
  672.             else {
  673.                 if ( strcmp (fs.dirname, "/") == 0 )
  674.                     (void) sprintf ( tmp, "%s%s", fs.dirname, name_select );
  675.                 else 
  676.                     (void) sprintf (tmp, "%s/%s", fs.dirname, name_select ); 
  677.             }
  678.             if ( ReadDir ( tmp ) == 0 ) {
  679.                 UpdateFileItem ( fs.select ); 
  680.                 fs.select = 0;
  681.                 RefreshDirWindow ( fs.dirname , FILESELECT );
  682.                 FirstPage ( fs.text );
  683.                 RefreshFileSelect ();
  684.             }
  685.             else
  686.                 RefreshDirWindow ( "Can't open dir", FILESELECT );
  687.         }
  688.         else {
  689.             fs.old_click = fs.click_time;
  690.             RefreshDirWindow ( fs.dirname, FILESELECT );
  691.         }
  692.     }
  693.     else
  694.         RefreshDirWindow ( "Stat error", FILESELECT );
  695.     if ( name_select != 0 )
  696.         (void) free (name_select); 
  697.     if ( tmp != 0 )
  698.             (void) free (tmp);
  699. }
  700.  
  701.  
  702. /*
  703. **    Function name : UpdateFileItem
  704. **
  705. **    Description : Allume ou eteint l'item courant.
  706. **    Input : Le no de l'item. 
  707. **    Ouput :
  708. */
  709. static void UpdateFileItem ( n )
  710.     register int n;
  711. {
  712.     register int y;
  713.  
  714.     if ( (n == 0)
  715.         || ( n < (fs.text -> no_current_line - fs.text -> n1))
  716.         || ( n > (fs.text -> no_current_line + fs.text -> n2)))
  717.         return;
  718.  
  719.     y = n - ( fs.text -> no_current_line - fs.text -> n1 );
  720.     y *= fs.text -> font_height;
  721.     y += MARGE;
  722.  
  723.     XFillRectangle ( dpy, fs.text -> window,
  724.         fs.text -> Igc, MARGE,  y, 
  725.         fs.text -> width - ( 2 * MARGE ),
  726.         fs.text -> font_height + 1 );
  727. }
  728.  
  729.  
  730. /*
  731. **    Function name : UnmapFileSelect
  732. **
  733. **    Description : Cache le file selecteur.
  734. **    Input : 
  735. **    Ouput :
  736. */
  737. static void UnmapFileSelect ()
  738. {
  739.     XUnmapSubwindows ( dpy, fs.main );
  740.     XUnmapWindow ( dpy, fs.main );
  741.     XUnmapSubwindows ( dpy, fs.frame );
  742.     XUnmapWindow ( dpy, fs.frame );
  743.  
  744.     XReparentWindow ( dpy, fs.frame, DefaultRootWindow (dpy), 0, 0 );
  745. }
  746.  
  747.  
  748. /*
  749. **    Function name : ConfigFileSelect
  750. **
  751. **    Description : Prepare l'affichage, geometrie etc...
  752. **    Input : La fenetre parent. 
  753. **    Ouput :
  754. */
  755. static void ConfigFileSelect ( parent )
  756.     Window parent;
  757. {
  758.     XWindowAttributes att;
  759.     register int width, height, x, y, i;
  760.  
  761.     XGetWindowAttributes ( dpy, parent, &att );
  762.     width = (att.width / 4) * 3;
  763.     height =  (att.height / 4) * 3;
  764.     x = att.width / 8;
  765.     y = att.height / 8;
  766.  
  767.             fs.m_width = width - FS_SHADOW;
  768.         fs.m_height = height - (2*fs.title_height) - FS_SHADOW;
  769.  
  770.         XReparentWindow ( dpy, fs.frame, parent, x, y );
  771.     XResizeWindow ( dpy, fs.frame, width, height );
  772.     XResizeWindow ( dpy, fs.shadow, width - FS_SHADOW , height - FS_SHADOW );
  773.     XResizeWindow ( dpy, fs.main, 
  774.         width - FS_SHADOW, height - (2*fs.title_height) - FS_SHADOW );
  775.     XResizeWindow ( dpy, fs.title,  width -FS_SHADOW , fs.title_height );
  776.         XResizeWindow ( dpy, fs.dir,  width -FS_SHADOW , fs.title_height );
  777.     XMoveWindow ( dpy, fs.ok, ( width/3 ) - ( fs.button_width/2 ), 
  778.                 fs.m_height - fs.title_height - FS_SPACE );
  779.     XMoveWindow ( dpy, fs.cancel, ( width*2 / 3 ) - ( fs.button_width/2 ), 
  780.                 fs.m_height - fs.title_height - FS_SPACE );
  781.     XMapSubwindows (dpy, fs.main );
  782.     XMapWindow ( dpy, fs.main );
  783.     XMapSubwindows ( dpy, fs.frame);
  784.     XMapRaised ( dpy, fs.frame);
  785.  
  786.     x = fs.m_height - (3 * FS_SPACE) -  fs.button_height; 
  787.     x -= ( 2 * MARGE );
  788.     i = x / fs.text -> font_height;
  789.     x = fs.m_height - (3 * FS_SPACE) -  fs.title_height;
  790.  
  791.     SetScrollLinePage (  fs.scroll, i ); 
  792.             ShowWindowText ( dpy, fs.text, 
  793.                 fs.m_width - GetScrollWidth () - 1 - ( 2 * FS_SPACE) , x );
  794.     i = fs.text -> no_current_line - fs.text -> n1 - 1;
  795.     RefreshScroll ( dpy,  fs.scroll,  fs.m_width - FS_SPACE, x, i );
  796. }
  797.